#include "analyse.h"
#include "macroblock.h"

void mb_analyse_init(h264_analyse_t *analyse)
{
    analyse->i_satd_i16x16 = COST_MAX;
    analyse->i_satd_chroma = COST_MAX;
}

static const intra16x16_pred_e i16x16_mode_available[5][5] =
{
    {I_PRED_16x16_DC_128, -1, -1, -1, -1},
    {I_PRED_16x16_DC_LEFT, I_PRED_16x16_H, -1, -1, -1},
    {I_PRED_16x16_DC_TOP, I_PRED_16x16_V, -1, -1, -1},
    {I_PRED_16x16_V, I_PRED_16x16_H, I_PRED_16x16_DC, -1, -1},
    {I_PRED_16x16_V, I_PRED_16x16_H, I_PRED_16x16_DC, I_PRED_16x16_P, -1},
};

static const intra_chroma_pred_e chroma_mode_available[5][5] =
{
    {I_PRED_CHROMA_DC_128, -1, -1, -1, -1},
    {I_PRED_CHROMA_DC_LEFT, I_PRED_CHROMA_H, -1, -1, -1},
    {I_PRED_CHROMA_DC_TOP, I_PRED_CHROMA_V, -1, -1, -1},
    {I_PRED_CHROMA_V, I_PRED_CHROMA_H, I_PRED_CHROMA_DC, -1, -1},
    {I_PRED_CHROMA_V, I_PRED_CHROMA_H, I_PRED_CHROMA_DC, I_PRED_CHROMA_P, -1},
};

const intra16x16_pred_e *predict_16x16_mode_available(int i_neighbour)
{
    int idx = i_neighbour & (MB_TOP|MB_LEFT|MB_TOPLEFT);
    if (idx == (MB_TOP|MB_LEFT|MB_TOPLEFT)) {
        idx = 4;
    } else {
        idx = idx & (MB_TOP|MB_LEFT);
    }
    
    return i16x16_mode_available[idx];
}

const intra_chroma_pred_e *predict_chroma_mode_available(int i_neighbour)
{
    int idx = i_neighbour & (MB_TOP|MB_LEFT|MB_TOPLEFT);
    if (idx == (MB_TOP|MB_LEFT|MB_TOPLEFT)) {
        idx = 4;
    } else {
        idx = idx & (MB_TOP|MB_LEFT);
    }
    
    return chroma_mode_available[idx];
}